<template>
  <div class="replay-drawer">
    <div class="drawer-header">
      <h3 class="drawer-title">
        <i class="el-icon-video-play"></i> 航迹回放控制
      </h3>
      <button class="close-btn" @click="closeDrawer">
        <i class="el-icon-close"></i>
      </button>
    </div>

    <div class="drawer-content">
      <!-- 文件选择区域 -->
      <div class="file-upload">
        <div class="upload-area" @click="triggerFileInput">
          <i class="el-icon-upload"></i>
          <p>点击或拖拽文件到此处</p>
          <p class="subtext">支持JSON格式航迹数据</p>
        </div>
        <input
          type="file"
          ref="fileInput"
          @change="handleFileChange"
          accept=".json"
          style="display: none"
        />

        <div v-if="replayFileName" class="file-name">
          <i class="el-icon-document"></i> {{ replayFileName }}
          <el-button
            type="danger"
            size="mini"
            icon="el-icon-delete"
            circle
            @click="clearFile"
          ></el-button>
        </div>
      </div>

      <!-- 时间轴区域 -->
      <div class="time-range-container" v-if="replayData">
        <div class="time-range-header">
          <div class="time-display">
            <span>开始时间: {{ formatTime(selectedStartTime) }}</span>
            <span>结束时间: {{ formatTime(selectedEndTime) }}</span>
          </div>
          <el-button type="primary" size="mini" @click="resetTimeRange"
            >重置范围</el-button
          >
        </div>

        <div class="timeline-container">
          <div class="time-labels">
            <span>{{ formatTime(minTime) }}</span>
            <span>{{ formatTime(maxTime) }}</span>
          </div>
          <div class="timeline-slider">
            <div class="timeline-track"></div>
            <div
              class="timeline-handle start-handle"
              @mousedown="startDrag('start')"
              :style="{ left: startPosition + '%' }"
            ></div>
            <div
              class="timeline-handle end-handle"
              @mousedown="startDrag('end')"
              :style="{ left: endPosition + '%' }"
            ></div>
            <div
              class="time-range"
              :style="{
                left: startPosition + '%',
                width: endPosition - startPosition + '%',
              }"
            ></div>
          </div>
        </div>
      </div>

      <!-- 回放控制区域 -->
      <div class="replay-controls">
        <div class="control-group">
          <el-button
            type="success"
            :disabled="!replayData"
            @click="startReplay"
            class="control-btn"
          >
            <i class="el-icon-video-play"></i>
            {{ isPaused ? "继续回放" : "开始回放" }}
          </el-button>

          <el-button
            type="warning"
            :disabled="!isReplaying || isPaused"
            @click="pauseReplay"
            class="control-btn"
          >
            <i class="el-icon-video-pause"></i> 暂停
          </el-button>

          <!-- <el-button
            type="danger"
            :disabled="!isReplaying"
            @click="stopReplay"
            class="control-btn"
          >
            <i class="el-icon-switch-button"></i> 停止
          </el-button> -->
        </div>

        <div class="speed-control">
          <span class="speed-label">倍速控制:</span>
          <el-slider
            v-model="playbackSpeed"
            :min="0.5"
            :max="10"
            :step="0.5"
            show-stops
            class="speed-slider"
          ></el-slider>
          <span class="speed-value">{{ playbackSpeed }}x</span>
        </div>
      </div>

      <!-- 回放进度 -->
      <div class="replay-progress" v-if="isReplaying">
        <div class="progress-header">
          <span>回放进度</span>
          <span>{{ currentReplayIndex + 1 }}/{{ filteredData.length }}</span>
        </div>
        <el-progress
          :percentage="replayProgress"
          :format="formatProgress"
          color="#409EFF"
          :show-text="false"
          class="progress-bar"
        ></el-progress>
      </div>

      <!-- 回放信息 -->
      <div class="replay-info">
        <div class="info-header"><i class="el-icon-info"></i> 回放信息</div>
        <div class="info-content">
          <div class="info-item">
            <label>文件类型:</label>
            <span>航迹回放数据</span>
          </div>
          <div class="info-item">
            <label>数据点数:</label>
            <span>{{ replayData ? replayData.length : 0 }} 个</span>
          </div>
          <div class="info-item">
            <label>回放点数:</label>
            <span>{{ filteredData.length }} 个</span>
          </div>
          <div class="info-item">
            <label>当前倍速:</label>
            <span>{{ playbackSpeed }}x</span>
          </div>
          <div class="info-item">
            <label>状态:</label>
            <span :class="statusClass">{{ replayStatus }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ReplayDrawer",
  props: {
    visible: Boolean,
  },
  data() {
    return {
      replayData: null, // 存储解析后的航迹数据
      replayResType: 2004, // 资源类型标识（默认2004）
      replayFileName: "",
      isReplaying: false,
      playbackSpeed: 1,
      replayTimer: null,
      currentReplayIndex: 0,
      replayProgress: 0,
      replayStatus: "未开始",
      isPaused: false,

      // 时间轴相关数据
      minTime: 0,
      maxTime: 0,
      selectedStartTime: 0,
      selectedEndTime: 0,
      startPosition: 0,
      endPosition: 100,
      dragging: false,
      dragType: null,
      filteredData: [],
    };
  },
  computed: {
    statusClass() {
      return {
        "status-active": this.isReplaying && !this.isPaused,
        "status-paused": this.isPaused,
        "status-inactive": !this.isReplaying,
      };
    },
  },
  methods: {
    closeDrawer() {
      this.stopReplay();
      this.$emit("close");
    },

    triggerFileInput() {
      this.$refs.fileInput.click();
    },

    handleFileChange(event) {
      const file = event.target.files[0];
      if (!file) return;

      // 验证文件类型
      if (!file.name.endsWith(".json")) {
        this.$message.error("请选择JSON格式的文件");
        return;
      }

      // 大文件处理（>10MB）
      if (file.size > 10 * 1024 * 1024) {
        this.$message.warning("大文件处理中，请稍候...");
        this.processLargeFile(file);
        return;
      }

      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const jsonData = JSON.parse(e.target.result);
          this.replayData = jsonData.data;
          this.replayResType = jsonData.resType;
          this.replayFileName = file.name;
          this.$message.success("航迹文件加载成功");
          this.replayStatus = "准备就绪";

          // 初始化时间轴
          this.initTimeline();
        } catch (error) {
          console.error("JSON解析错误:", error);
          this.$message.error("文件解析失败，请确保文件格式正确");
          this.replayStatus = "文件错误";
        }
      };

      reader.onerror = () => {
        this.$message.error("文件读取失败");
        this.replayStatus = "读取错误";
      };

      reader.readAsText(file);
    },

    async processLargeFile(file) {
      try {
        const text = await this.readFileAsText(file);
        const jsonData = JSON.parse(text);
        this.replayData = jsonData.data;
        this.replayResType = jsonData.resType;
        this.replayFileName = file.name;
        this.$message.success("大文件加载成功");
        this.replayStatus = "准备就绪";

        // 初始化时间轴
        this.initTimeline();
      } catch (error) {
        console.error("大文件处理错误:", error);
        this.$message.error("大文件处理失败");
        this.replayStatus = "文件错误";
      }
    },

    readFileAsText(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = reject;
        reader.readAsText(file);
      });
    },

    clearFile() {
      this.stopReplay();
      this.replayData = null;
      this.replayResType = null;
      this.replayFileName = "";
      this.replayStatus = "未开始";
      this.$emit("clear-replay-tracks");
    },

    startReplay() {
      if (!this.replayData || this.replayData.length === 0) {
        this.$message.warning("没有可回放的航迹数据");
        return;
      }

      if (this.isReplaying && this.isPaused) {
        // 继续回放
        this.isPaused = false;
        this.replayStatus = "回放中";
        this.playNextPoint();
        return;
      }

      // 新的回放
      this.isReplaying = true;
      this.isPaused = false;
      this.replayStatus = "回放中";

      // 过滤选定时间范围内的数据
      this.filteredData = this.replayData.filter((point) => {
        const pointTime = new Date(point.sendTime).getTime();
        return (
          pointTime >= this.selectedStartTime &&
          pointTime <= this.selectedEndTime
        );
      });

      if (this.filteredData.length === 0) {
        this.$message.warning("选定时间段内没有可回放的数据");
        this.replayStatus = "无数据";
        this.isReplaying = false;
        return;
      }

      this.currentReplayIndex = 0;
      this.playNextPoint();
    },

    pauseReplay() {
      if (this.replayTimer) {
        clearTimeout(this.replayTimer);
        this.replayTimer = null;
      }
      this.isPaused = true;
      this.replayStatus = "已暂停";
      this.$message.info("回放已暂停");
    },

    playNextPoint() {
      if (this.currentReplayIndex >= this.filteredData.length) {
        this.stopReplay();
        this.$message.success("航迹回放完成");
        this.replayStatus = "回放完成";
        return;
      }

      const dataPoint = this.filteredData[this.currentReplayIndex];
      this.$emit("replay-data", dataPoint, this.replayResType);

      this.currentReplayIndex++;
      this.replayProgress = Math.round(
        (this.currentReplayIndex / this.filteredData.length) * 100
      );

      // 根据倍速设置间隔
      const interval = 1000 / this.playbackSpeed;
      this.replayTimer = setTimeout(() => {
        this.playNextPoint();
      }, interval);
    },

    stopReplay() {
      this.isReplaying = false;
      this.isPaused = false;
      if (this.replayTimer) {
        clearTimeout(this.replayTimer);
        this.replayTimer = null;
      }
      this.replayProgress = 0;
      this.replayStatus = "已停止";
      this.$emit("replay-stopped");
      this.$message.info("回放已停止");
    },

    formatProgress() {
      return `回放进度: ${this.currentReplayIndex}/${this.filteredData.length}`;
    },

    // 时间轴相关方法
    initTimeline() {
      if (!this.replayData || this.replayData.length === 0) return;

      // 提取所有时间戳并排序
      const timestamps = this.replayData
        .filter((item) => item.sendTime)
        .map((item) => new Date(item.sendTime).getTime());

      if (timestamps.length === 0) return;

      this.minTime = Math.min(...timestamps);
      this.maxTime = Math.max(...timestamps);

      // 设置默认选择范围为全部
      this.selectedStartTime = this.minTime;
      this.selectedEndTime = this.maxTime;

      // 位置百分比
      this.startPosition = 0;
      this.endPosition = 100;
    },

    formatTime(timestamp) {
      if (!timestamp) return "--:--:--";
      const date = new Date(timestamp);
      return `${date.getFullYear()}-${(date.getMonth() + 1)
        .toString()
        .padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")} ${date
        .getHours()
        .toString()
        .padStart(2, "0")}:${date
        .getMinutes()
        .toString()
        .padStart(2, "0")}:${date.getSeconds().toString().padStart(2, "0")}`;
    },

    startDrag(type) {
      this.dragType = type;
      this.dragging = true;
      document.addEventListener("mousemove", this.handleDrag);
      document.addEventListener("mouseup", this.stopDrag);
    },

    handleDrag(e) {
      if (!this.dragging) return;

      const timeline = this.$el.querySelector(".timeline-slider");
      const rect = timeline.getBoundingClientRect();
      const position = Math.max(
        0,
        Math.min(100, ((e.clientX - rect.left) / rect.width) * 100)
      );

      if (this.dragType === "start") {
        if (position < this.endPosition - 5) {
          // 防止重叠
          this.startPosition = position;
          this.selectedStartTime =
            this.minTime + (position / 100) * (this.maxTime - this.minTime);
        }
      } else {
        if (position > this.startPosition + 5) {
          // 防止重叠
          this.endPosition = position;
          this.selectedEndTime =
            this.minTime + (position / 100) * (this.maxTime - this.minTime);
        }
      }
    },

    stopDrag() {
      this.dragging = false;
      document.removeEventListener("mousemove", this.handleDrag);
      document.removeEventListener("mouseup", this.stopDrag);
    },

    resetTimeRange() {
      this.selectedStartTime = this.minTime;
      this.selectedEndTime = this.maxTime;
      this.startPosition = 0;
      this.endPosition = 100;
    },
  },
  beforeDestroy() {
    this.stopReplay();
    document.removeEventListener("mousemove", this.handleDrag);
    document.removeEventListener("mouseup", this.stopDrag);
  },
};
</script>

<style lang="less" scoped>
.replay-drawer {
  position: fixed;
  top: 0;
  right: 0;
  width: 380px;
  height: 100vh;
  background: rgba(20, 30, 50, 0.95);
  backdrop-filter: blur(10px);
  border-left: 1px solid rgba(64, 158, 255, 0.5);
  box-shadow: -5px 0 15px rgba(0, 0, 0, 0.5);
  z-index: 2000;
  display: flex;
  flex-direction: column;
  color: #d0e0f0;
  font-family: "Microsoft YaHei", sans-serif;
  overflow: hidden;

  .drawer-header {
    padding: 15px 20px;
    background: rgba(30, 50, 80, 0.8);
    border-bottom: 1px solid rgba(64, 158, 255, 0.3);
    display: flex;
    justify-content: space-between;
    align-items: center;

    .drawer-title {
      margin: 0;
      color: #409eff;
      font-size: 18px;
      display: flex;
      align-items: center;
      font-weight: 600;

      i {
        margin-right: 10px;
        font-size: 20px;
      }
    }

    .close-btn {
      background: rgba(100, 30, 30, 0.4);
      border: 1px solid rgba(255, 80, 80, 0.3);
      color: #ffa0a0;
      font-size: 16px;
      cursor: pointer;
      padding: 5px;
      border-radius: 50%;
      width: 32px;
      height: 32px;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.3s;

      &:hover {
        background: rgba(150, 40, 40, 0.7);
        color: white;
        transform: rotate(90deg);
      }
    }
  }

  .drawer-content {
    flex: 1;
    padding: 20px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 20px;
  }

  .file-upload {
    .upload-area {
      border: 2px dashed rgba(64, 158, 255, 0.3);
      border-radius: 8px;
      padding: 0px 20px;
      text-align: center;
      cursor: pointer;
      transition: all 0.3s;
      background: rgba(25, 40, 65, 0.5);
      position: relative;
      overflow: hidden;

      &:hover {
        border-color: #409eff;
        background: rgba(35, 60, 95, 0.7);
        box-shadow: 0 0 15px rgba(64, 158, 255, 0.2);

        &::before {
          content: "";
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          height: 3px;
          background: linear-gradient(90deg, transparent, #409eff, transparent);
          animation: highlight 2s infinite linear;
        }
      }

      i {
        font-size: 48px;
        color: #409eff;
        margin-bottom: 15px;
        transition: transform 0.3s;
      }

      p {
        margin: 5px 0;
        font-size: 16px;
        font-weight: 500;
      }

      .subtext {
        font-size: 12px;
        color: #a0b9d9;
      }
    }

    .file-name {
      margin-top: 15px;
      padding: 10px 15px;
      background: rgba(30, 60, 100, 0.5);
      border-radius: 6px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      border: 1px solid rgba(64, 158, 255, 0.2);
      transition: all 0.3s;

      &:hover {
        border-color: #409eff;
        background: rgba(40, 70, 110, 0.6);
      }

      i {
        margin-right: 8px;
        color: #409eff;
      }
    }
  }

  /* 时间范围选择器 */
  .time-range-container {
    background: rgba(25, 40, 65, 0.7);
    border-radius: 8px;
    padding: 15px;
    border: 1px solid rgba(64, 158, 255, 0.2);

    .time-range-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;

      .time-display {
        display: flex;
        flex-direction: column;
        gap: 5px;
        font-size: 14px;
      }
    }

    .timeline-container {
      .time-labels {
        display: flex;
        justify-content: space-between;
        margin-bottom: 8px;
        font-size: 12px;
        color: #a0c0e0;
      }

      .timeline-slider {
        position: relative;
        height: 30px;
        cursor: pointer;

        .timeline-track {
          position: absolute;
          top: 50%;
          transform: translateY(-50%);
          width: 100%;
          height: 4px;
          background: rgba(100, 120, 150, 0.4);
          border-radius: 2px;
        }

        .timeline-handle {
          position: absolute;
          top: 50%;
          transform: translate(-50%, -50%);
          width: 16px;
          height: 16px;
          background: #fff;
          border: 2px solid #409eff;
          border-radius: 50%;
          cursor: pointer;
          box-shadow: 0 0 8px rgba(64, 158, 255, 0.5);
          z-index: 10;
          transition: transform 0.2s;

          &:hover {
            transform: translate(-50%, -50%) scale(1.2);
          }
        }

        .start-handle {
          z-index: 11;
        }

        .time-range {
          position: absolute;
          top: 50%;
          transform: translateY(-50%);
          height: 6px;
          background: linear-gradient(90deg, #409eff, #66b1ff);
          border-radius: 3px;
          z-index: 9;
        }
      }
    }
  }

  .replay-controls {
    padding: 15px;
    background: rgba(25, 40, 65, 0.7);
    border-radius: 8px;
    border: 1px solid rgba(64, 158, 255, 0.2);

    .control-group {
      display: flex;
      gap: 10px;
      margin-bottom: 20px;
      flex-wrap: wrap;

      .control-btn {
        flex: 1;
        min-width: 100px;
        padding: 10px 0;
        font-size: 14px;
        transition: all 0.3s;

        &:hover {
          transform: translateY(-2px);
          box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }

        &:active {
          transform: translateY(1px);
        }
      }
    }

    .speed-control {
      display: flex;
      align-items: center;
      gap: 12px;

      .speed-label {
        font-size: 14px;
        color: #a0c0e0;
        min-width: 70px;
      }

      .speed-slider {
        flex: 1;

        ::v-deep .el-slider__runway {
          background-color: rgba(100, 120, 150, 0.4);
        }

        ::v-deep .el-slider__bar {
          background-color: #409eff;
        }
      }

      .speed-value {
        min-width: 50px;
        text-align: center;
        background: rgba(64, 158, 255, 0.2);
        padding: 5px 10px;
        border-radius: 4px;
        font-weight: bold;
        color: #d0e0f0;
      }
    }
  }

  .replay-progress {
    padding: 15px;
    background: rgba(25, 40, 65, 0.7);
    border-radius: 8px;
    border: 1px solid rgba(64, 158, 255, 0.2);

    .progress-header {
      display: flex;
      justify-content: space-between;
      margin-bottom: 10px;
      font-size: 14px;
      color: #a0c0e0;
    }

    .progress-bar {
      ::v-deep .el-progress-bar__outer {
        background-color: rgba(100, 120, 150, 0.4);
        border-radius: 10px;
      }

      ::v-deep .el-progress-bar__inner {
        border-radius: 10px;
        background: linear-gradient(90deg, #409eff, #66b1ff);
      }
    }
  }

  .replay-info {
    background: rgba(25, 40, 65, 0.7);
    border-radius: 8px;
    border: 1px solid rgba(64, 158, 255, 0.2);
    overflow: hidden;

    .info-header {
      padding: 12px 15px;
      background: rgba(30, 50, 80, 0.8);
      border-bottom: 1px solid rgba(64, 158, 255, 0.3);
      font-weight: bold;
      color: #409eff;
      display: flex;
      align-items: center;

      i {
        margin-right: 8px;
        font-size: 16px;
      }
    }

    .info-content {
      padding: 15px;
    }

    .info-item {
      display: flex;
      margin-bottom: 12px;
      font-size: 14px;

      label {
        width: 100px;
        color: #a0c0e0;
      }

      span {
        flex: 1;
        color: white;
        font-weight: 500;

        &.status-active {
          color: #67c23a;
        }

        &.status-paused {
          color: #e6a23c;
        }

        &.status-inactive {
          color: #f56c6c;
        }
      }
    }
  }
}

@keyframes highlight {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}
</style>
